﻿#region File and License Information
/*
<File>
	<License>
		Copyright © 2009 - 2017, Daniel Vaughan. All rights reserved.
		This file is part of Calcium (http://calciumsdk.net), 
		which is released under the MIT License.
		See file /Documentation/License.txt for details.
	</License>
	<CreationDate>2013-03-21 20:07:26Z</CreationDate>
</File>
*/
#endregion

using System;
using System.Collections.Generic;
using System.Globalization;

using Outcoder.Globalization;

namespace Outcoder.Globalization
{
	/// <summary>
	/// In Windows Phone, the <see cref="CultureInfo"/> class does not include a LCID property.
	/// This class provides a means to convert to and from culture names and locale ID values.
	/// </summary>
	public static class CultureNameToLocaleIdConverter
	{
		/// <summary>
		/// Converts the specified LCID value to a culture name, such as en-US.
		/// </summary>
		/// <param name="localeId">An int representing the culture name.</param>
		/// <returns>The RFC 1766 culture name, such as en-US.</returns>
		public static string ConvertLocaleIdToCultureName(short localeId)
		{
			string result;

			if (!lcidToNameDictionary.TryGetValue(localeId, out result))
			{
				throw new Exception("Unable to match specified Locale ID " + localeId);
			}

			return result;
		}

		/// <summary>
		/// Converts the specified RFC 1766 culture name to a lcid value.
		/// </summary>
		/// <param name="cultureName">The RFC 1766 culture name value in the form e.g. en-US.</param>
		/// <returns>An int representing the culture name.</returns>
		public static short ConvertCultureNameToLocaleId(string cultureName)
		{
			return ConvertToLocaleId(cultureName);
		}

		internal static short ConvertToLocaleId(string cultureName)
		{
			if (cultureName == null)
			{
				throw new ArgumentNullException();
			}

			short result;

			if (!nameToLcidDictionary.TryGetValue(cultureName, out result))
			{
				throw new Exception("Unable to match specified culture " + cultureName);
			}

			return result;
		}

		public static void SetMapping(string cultureName, short localeId)
		{
			nameToLcidDictionary[cultureName] = localeId;
			lcidToNameDictionary[localeId] = cultureName;
		}

		static readonly Dictionary<string, short> nameToLcidDictionary = new Dictionary<string, short>
			{
				{string.Empty, 0x007F},

				{"Az-Latn-AZ", 0x042c},
				{"fil-PH", 0x0464},
				{"ha-Latn-NG", 0x0468},
				{"nb-NO", 0x0414},
				{"sr-Latn-CS", 0x081a},
				{"uz-Latn-UZ", 0x0443},

				{"af", 0x0036},
				{"af-ZA", 0x0436},
				{"sq", 0x001C},
				{"sq-AL", 0x041C},
				{"ar", 0x0001},
				{"ar-DZ", 0x1401},
				{"ar-BH", 0x3C01},
				{"ar-EG", 0x0C01},
				{"ar-IQ", 0x0801},
				{"ar-JO", 0x2C01},
				{"ar-KW", 0x3401},
				{"ar-LB", 0x3001},
				{"ar-LY", 0x1001},
				{"ar-MA", 0x1801},
				{"ar-OM", 0x2001},
				{"ar-QA", 0x4001},
				{"ar-SA", 0x0401},
				{"ar-SY", 0x2801},
				{"ar-TN", 0x1C01},
				{"ar-AE", 0x3801},
				{"ar-YE", 0x2401},
				{"hy", 0x002B},
				{"hy-AM", 0x042B},
				{"az", 0x002C},
				{"Cy-az-AZ", 0x082C},
				{"Lt-az-AZ", 0x042C},
				{"eu", 0x002D},
				{"eu-ES", 0x042D},
				{"be", 0x0023},
				{"be-BY", 0x0423},
				{"bg", 0x0002},
				{"bg-BG", 0x0402},
				{"ca", 0x0003},
				{"ca-ES", 0x0403},
				{"zh-HK", 0x0C04},
				{"zh-MO", 0x1404},
				{"zh-CN", 0x0804},
				{"zh-CHS", 0x0004},
				{"zh-SG", 0x1004},
				{"zh-TW", 0x0404},
				{"zh-CHT", 0x7C04},
				{"hr", 0x001A},
				{"hr-HR", 0x041A},
				{"cs", 0x0005},
				{"cs-CZ", 0x0405},
				{"da", 0x0006},
				{"da-DK", 0x0406},
				{"div", 0x0065},
				{"div-MV", 0x0465},
				{"nl", 0x0013},
				{"nl-BE", 0x0813},
				{"nl-NL", 0x0413},
				{"en", 0x0009},
				{"en-AU", 0x0C09},
				{"en-BZ", 0x2809},
				{"en-CA", 0x1009},
				{"en-CB", 0x2409},
				{"en-IE", 0x1809},
				{"en-JM", 0x2009},
				{"en-NZ", 0x1409},
				{"en-PH", 0x3409},
				{"en-ZA", 0x1C09},
				{"en-TT", 0x2C09},
				{"en-GB", 0x0809},
				{"en-US", 0x0409},
				{"en-ZW", 0x3009},
				{"et", 0x0025},
				{"et-EE", 0x0425},
				{"fo", 0x0038},
				{"fo-FO", 0x0438},
				{"fa", 0x0029},
				{"fa-IR", 0x0429},
				{"fi", 0x000B},
				{"fi-FI", 0x040B},
				{"fr", 0x000C},
				{"fr-BE", 0x080C},
				{"fr-CA", 0x0C0C},
				{"fr-FR", 0x040C},
				{"fr-LU", 0x140C},
				{"fr-MC", 0x180C},
				{"fr-CH", 0x100C},
				{"gl", 0x0056},
				{"gl-ES", 0x0456},
				{"ka", 0x0037},
				{"ka-GE", 0x0437},
				{"de", 0x0007},
				{"de-AT", 0x0C07},
				{"de-DE", 0x0407},
				{"de-LI", 0x1407},
				{"de-LU", 0x1007},
				{"de-CH", 0x0807},
				{"el", 0x0008},
				{"el-GR", 0x0408},
				{"gu", 0x0047},
				{"gu-IN", 0x0447},
				{"he", 0x000D},
				{"he-IL", 0x040D},
				{"hi", 0x0039},
				{"hi-IN", 0x0439},
				{"hu", 0x000E},
				{"hu-HU", 0x040E},
				{"is", 0x000F},
				{"is-IS", 0x040F},
				{"id", 0x0021},
				{"id-ID", 0x0421},
				{"it", 0x0010},
				{"it-IT", 0x0410},
				{"it-CH", 0x0810},
				{"ja", 0x0011},
				{"ja-JP", 0x0411},
				{"kn", 0x004B},
				{"kn-IN", 0x044B},
				{"kk", 0x003F},
				{"kk-KZ", 0x043F},
				{"kok", 0x0057},
				{"kok-IN", 0x0457},
				{"ko", 0x0012},
				{"ko-KR", 0x0412},
				{"ky", 0x0040},
				{"ky-KZ", 0x0440},
				{"lv", 0x0026},
				{"lv-LV", 0x0426},
				{"lt", 0x0027},
				{"lt-LT", 0x0427},
				{"mk", 0x002F},
				{"mk-MK", 0x042F},
				{"ms", 0x003E},
				{"ms-BN", 0x083E},
				{"ms-MY", 0x043E},
				{"mr", 0x004E},
				{"mr-IN", 0x044E},
				{"mn", 0x0050},
				{"mn-MN", 0x0450},
				{"no", 0x0014},
				{"nn-NO", 0x0814},
				{"pl", 0x0015},
				{"pl-PL", 0x0415},
				{"pt", 0x0016},
				{"pt-BR", 0x0416},
				{"pt-PT", 0x0816},
				{"pa", 0x0046},
				{"pa-IN", 0x0446},
				{"ro", 0x0018},
				{"ro-RO", 0x0418},
				{"ru", 0x0019},
				{"ru-RU", 0x0419},
				{"sa", 0x004F},
				{"sa-IN", 0x044F},
				{"Cy-sr-SP", 0x0C1A},
				{"Lt-sr-SP", 0x081A},
				{"sk", 0x001B},
				{"sk-SK", 0x041B},
				{"sl", 0x0024},
				{"sl-SI", 0x0424},
				{"es", 0x000A},
				{"es-AR", 0x2C0A},
				{"es-BO", 0x400A},
				{"es-CL", 0x340A},
				{"es-CO", 0x240A},
				{"es-CR", 0x140A},
				{"es-DO", 0x1C0A},
				{"es-EC", 0x300A},
				{"es-SV", 0x440A},
				{"es-GT", 0x100A},
				{"es-HN", 0x480A},
				{"es-MX", 0x080A},
				{"es-NI", 0x4C0A},
				{"es-PA", 0x180A},
				{"es-PY", 0x3C0A},
				{"es-PE", 0x280A},
				{"es-PR", 0x500A},
				{"es-ES", 0x0C0A},
				{"es-UY", 0x380A},
				{"es-VE", 0x200A},
				{"sw", 0x0041},
				{"sw-KE", 0x0441},
				{"sv", 0x001D},
				{"sv-FI", 0x081D},
				{"sv-SE", 0x041D},
				{"syr", 0x005A},
				{"syr-SY", 0x045A},
				{"ta", 0x0049},
				{"ta-IN", 0x0449},
				{"tt", 0x0044},
				{"tt-RU", 0x0444},
				{"te", 0x004A},
				{"te-IN", 0x044A},
				{"th", 0x001E},
				{"th-TH", 0x041E},
				{"tr", 0x001F},
				{"tr-TR", 0x041F},
				{"uk", 0x0022},
				{"uk-UA", 0x0422},
				{"ur", 0x0020},
				{"ur-PK", 0x0420},
				{"uz", 0x0043},
				{"Cy-uz-UZ", 0x0843},
				{"Lt-uz-UZ", 0x0443},
				{"vi", 0x002A},
				{"vi-VN", 0x042A},
			};

		static readonly Dictionary<short, string> lcidToNameDictionary
			= new Dictionary<short, string>
			{
				{0x007F, string.Empty},

				{0x042c, "Az-Latn-AZ"},
				{0x0464, "fil-PH"},
				{0x0468, "ha-Latn-NG"},
				{0x0414, "nb-NO"},
				{0x081a, "sr-Latn-CS"},
				{0x0443, "uz-Latn-UZ"},

				{0x0036, "af"},
				{0x0436, "af-ZA"},
				{0x001C, "sq"},
				{0x041C, "sq-AL"},
				{0x0001, "ar"},
				{0x1401, "ar-DZ"},
				{0x3C01, "ar-BH"},
				{0x0C01, "ar-EG"},
				{0x0801, "ar-IQ"},
				{0x2C01, "ar-JO"},
				{0x3401, "ar-KW"},
				{0x3001, "ar-LB"},
				{0x1001, "ar-LY"},
				{0x1801, "ar-MA"},
				{0x2001, "ar-OM"},
				{0x4001, "ar-QA"},
				{0x0401, "ar-SA"},
				{0x2801, "ar-SY"},
				{0x1C01, "ar-TN"},
				{0x3801, "ar-AE"},
				{0x2401, "ar-YE"},
				{0x002B, "hy"},
				{0x042B, "hy-AM"},
				{0x002C, "az"},
				{0x082C, "Cy-az-AZ"},
				//{0x042C, "Lt-az-AZ"},
				{0x002D, "eu"},
				{0x042D, "eu-ES"},
				{0x0023, "be"},
				{0x0423, "be-BY"},
				{0x0002, "bg"},
				{0x0402, "bg-BG"},
				{0x0003, "ca"},
				{0x0403, "ca-ES"},
				{0x0C04, "zh-HK"},
				{0x1404, "zh-MO"},
				{0x0804, "zh-CN"},
				{0x0004, "zh-CHS"},
				{0x1004, "zh-SG"},
				{0x0404, "zh-TW"},
				{0x7C04, "zh-CHT"},
				{0x001A, "hr"},
				{0x041A, "hr-HR"},
				{0x0005, "cs"},
				{0x0405, "cs-CZ"},
				{0x0006, "da"},
				{0x0406, "da-DK"},
				{0x0065, "div"},
				{0x0465, "div-MV"},
				{0x0013, "nl"},
				{0x0813, "nl-BE"},
				{0x0413, "nl-NL"},
				{0x0009, "en"},
				{0x0C09, "en-AU"},
				{0x2809, "en-BZ"},
				{0x1009, "en-CA"},
				{0x2409, "en-CB"},
				{0x1809, "en-IE"},
				{0x2009, "en-JM"},
				{0x1409, "en-NZ"},
				{0x3409, "en-PH"},
				{0x1C09, "en-ZA"},
				{0x2C09, "en-TT"},
				{0x0809, "en-GB"},
				{0x0409, "en-US"},
				{0x3009, "en-ZW"},
				{0x0025, "et"},
				{0x0425, "et-EE"},
				{0x0038, "fo"},
				{0x0438, "fo-FO"},
				{0x0029, "fa"},
				{0x0429, "fa-IR"},
				{0x000B, "fi"},
				{0x040B, "fi-FI"},
				{0x000C, "fr"},
				{0x080C, "fr-BE"},
				{0x0C0C, "fr-CA"},
				{0x040C, "fr-FR"},
				{0x140C, "fr-LU"},
				{0x180C, "fr-MC"},
				{0x100C, "fr-CH"},
				{0x0056, "gl"},
				{0x0456, "gl-ES"},
				{0x0037, "ka"},
				{0x0437, "ka-GE"},
				{0x0007, "de"},
				{0x0C07, "de-AT"},
				{0x0407, "de-DE"},
				{0x1407, "de-LI"},
				{0x1007, "de-LU"},
				{0x0807, "de-CH"},
				{0x0008, "el"},
				{0x0408, "el-GR"},
				{0x0047, "gu"},
				{0x0447, "gu-IN"},
				{0x000D, "he"},
				{0x040D, "he-IL"},
				{0x0039, "hi"},
				{0x0439, "hi-IN"},
				{0x000E, "hu"},
				{0x040E, "hu-HU"},
				{0x000F, "is"},
				{0x040F, "is-IS"},
				{0x0021, "id"},
				{0x0421, "id-ID"},
				{0x0010, "it"},
				{0x0410, "it-IT"},
				{0x0810, "it-CH"},
				{0x0011, "ja"},
				{0x0411, "ja-JP"},
				{0x004B, "kn"},
				{0x044B, "kn-IN"},
				{0x003F, "kk"},
				{0x043F, "kk-KZ"},
				{0x0057, "kok"},
				{0x0457, "kok-IN"},
				{0x0012, "ko"},
				{0x0412, "ko-KR"},
				{0x0040, "ky"},
				{0x0440, "ky-KZ"},
				{0x0026, "lv"},
				{0x0426, "lv-LV"},
				{0x0027, "lt"},
				{0x0427, "lt-LT"},
				{0x002F, "mk"},
				{0x042F, "mk-MK"},
				{0x003E, "ms"},
				{0x083E, "ms-BN"},
				{0x043E, "ms-MY"},
				{0x004E, "mr"},
				{0x044E, "mr-IN"},
				{0x0050, "mn"},
				{0x0450, "mn-MN"},
				{0x0014, "no"},
				{0x0814, "nn-NO"},
				{0x0015, "pl"},
				{0x0415, "pl-PL"},
				{0x0016, "pt"},
				{0x0416, "pt-BR"},
				{0x0816, "pt-PT"},
				{0x0046, "pa"},
				{0x0446, "pa-IN"},
				{0x0018, "ro"},
				{0x0418, "ro-RO"},
				{0x0019, "ru"},
				{0x0419, "ru-RU"},
				{0x004F, "sa"},
				{0x044F, "sa-IN"},
				{0x0C1A, "Cy-sr-SP"},
				//{0x081A, "Lt-sr-SP"},
				{0x001B, "sk"},
				{0x041B, "sk-SK"},
				{0x0024, "sl"},
				{0x0424, "sl-SI"},
				{0x000A, "es"},
				{0x2C0A, "es-AR"},
				{0x400A, "es-BO"},
				{0x340A, "es-CL"},
				{0x240A, "es-CO"},
				{0x140A, "es-CR"},
				{0x1C0A, "es-DO"},
				{0x300A, "es-EC"},
				{0x440A, "es-SV"},
				{0x100A, "es-GT"},
				{0x480A, "es-HN"},
				{0x080A, "es-MX"},
				{0x4C0A, "es-NI"},
				{0x180A, "es-PA"},
				{0x3C0A, "es-PY"},
				{0x280A, "es-PE"},
				{0x500A, "es-PR"},
				{0x0C0A, "es-ES"},
				{0x380A, "es-UY"},
				{0x200A, "es-VE"},
				{0x0041, "sw"},
				{0x0441, "sw-KE"},
				{0x001D, "sv"},
				{0x081D, "sv-FI"},
				{0x041D, "sv-SE"},
				{0x005A, "syr"},
				{0x045A, "syr-SY"},
				{0x0049, "ta"},
				{0x0449, "ta-IN"},
				{0x0044, "tt"},
				{0x0444, "tt-RU"},
				{0x004A, "te"},
				{0x044A, "te-IN"},
				{0x001E, "th"},
				{0x041E, "th-TH"},
				{0x001F, "tr"},
				{0x041F, "tr-TR"},
				{0x0022, "uk"},
				{0x0422, "uk-UA"},
				{0x0020, "ur"},
				{0x0420, "ur-PK"},
				{0x0043, "uz"},
				{0x0843, "Cy-uz-UZ"},
				//{0x0443, "Lt-uz-UZ"},
				{0x002A, "vi"},
				{0x042A, "vi-VN"},
			};
	}
}

namespace System.Globalization
{
	public static class CultureInfoExtensions
	{
		/// <summary>
		/// Retrieves the Locale ID value for the specified <c>CultureInfo</c> instance.
		/// This is analogous to the LCID property of .NET 4.5.
		/// </summary>
		/// <param name="cultureInfo">The <c>CultureInfo</c> object.</param>
		/// <returns>The Locale ID value representing the culture name 
		/// of the specified <c>CultureInfo</c>.</returns>
		public static short GetLcid(this CultureInfo cultureInfo)
		{
			if (cultureInfo == null)
			{
				throw new ArgumentNullException();
			}

			string name = cultureInfo.Name;

			return CultureNameToLocaleIdConverter.ConvertToLocaleId(name);
		}
	}
}